package com.yequan.exe.core;

import com.yequan.exe.core.handler.ExeHandler;
import com.yequan.exe.core.task.ExeExecutorTask;
import com.yequan.exe.service.CalcDbService;
import com.yequan.mqservice.ResultMsgProducerService;
import com.yequan.pojo.CalcData;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author yq
 * @date 2020/09/29
 */
@Service("exeExecutor")
public class ExeExecutor implements ApplicationContextAware {

    private ApplicationContext applicationContext;
    private static Map<String, ExeHandler> exeHandlerMap;
    private static ExecutorService executorService;
    @Resource(name = "calcDbService")
    private CalcDbService calcDbService;

    @Resource(name = "resultMsgProducerService")
    private ResultMsgProducerService resultMsgProducerService;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void init() {
        executorService = Executors.newFixedThreadPool(10);
        exeHandlerMap = applicationContext.getBeansOfType(ExeHandler.class);
    }

    public void execute(CalcData calcData) {
        String serviceName = calcData.getExeInfo().getServiceName();
        if (exeHandlerMap.containsKey(serviceName)) {
            ExeHandler exeHandler = exeHandlerMap.get(serviceName);
            if (null != exeHandler) {
                exeHandler.registryDbService(calcDbService);
                exeHandler.registryResultMsgMQService(resultMsgProducerService);
                executorService.submit(new ExeExecutorTask(exeHandler, calcData));
            } else {
                System.out.println("不支持的计算类型。。。");
            }
        } else {
            System.out.println("不支持的计算类型。。。");
        }
    }

    public void destroy() {
        if (null != executorService) {
            gracefulShutdown(executorService);
        }
    }

    private void gracefulShutdown(ExecutorService executorService) {
        System.out.println("线程池开始关闭");
        try {
            executorService.shutdown();
            if (!executorService.awaitTermination(20, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
                System.out.println("线程池已停止");
                if (!executorService.awaitTermination(20, TimeUnit.SECONDS)) {
                    System.out.println("线程池停止失败");
                }
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
            e.printStackTrace();
        }
    }

}
